# 编译器设置
CXX = g++
CXXFLAGS = -std=c++11 -Wall -g

# 项目结构设置（相对路径，基于Makefile所在目录）
SRC_DIR = src		# 源文件目录（SecondEdition/src）
INC_DIR = include	# 头文件目录（SecondEdition/include）
OBJ_DIR = obj		# 目标文件目录（SecondEdition/obj）
BIN_DIR = bin		# 可执行文件目录（SecondEdition/bin）

# 可执行文件名称
TARGET = $(BIN_DIR)/server

# 自动查找源文件和头文件
SRCS = $(wildcard $(SRC_DIR)/*.cpp)	# 所有src目录下的.cpp文件
OBJS = $(patsubst $(SRC_DIR)/%.cpp, $(OBJ_DIR)/%.o, $(SRCS)) # 对应的.obj文件

# 自动生成依赖规则（处理头文件修改后重新编译）
DEPFLAGS = -MT $@ -MMD -MP -MF $(OBJ_DIR)/$*.Td

# 编译命令（指定头文件路径、生成目标文件）
COMPILE.cpp = $(CXX) $(DEPFLAGS) $(CXXFLAGS) -I$(INC_DIR) -c -o $@

# 链接命令（将目标文件链接为可执行文件）
LINK.cpp = $(CXX) $(CXXFLAGS) -o $@

# 默认目标：编译生成可执行文件
all: $(TARGET)

# 创建目录
$(shell mkdir -p $(OBJ_DIR) $(BIN_DIR))

# 链接目标文件生成可执行文件
# $^ 表示所有依赖的目标文件（OBJS）
$(TARGET): $(OBJS)
	$(LINK.cpp) $^	

# 编译源文件生成目标文件（模式规则：匹配所有.cpp文件）
# $< 表示第一个依赖文件（对应的.cpp）
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp $(OBJ_DIR)/%.d | $(OBJ_DIR)
	$(COMPILE.cpp) $<
	@mv -f $(OBJ_DIR)/$*.Td $(OBJ_DIR)/$*.d

# 依赖文件规则（防止Make报错）
$(OBJ_DIR)/%.d: ;

# 包含所有依赖文件（确保头文件修改后触发重新编译）
-include $(wildcard $(OBJ_DIR)/*.d)

# 清理规则
clean:
	rm -rf $(OBJ_DIR) $(BIN_DIR)
	
# 声明伪目标（避免与同名文件冲突）
.PHONY: all clean